package com.crm.custinfo.service.impl;

import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;

import com.alibaba.fastjson2.JSONObject;
import com.crm.custinfo.domain.CustCommentRecord;
import com.crm.custinfo.domain.HitPackage;
import com.crm.custinfo.service.ICustCommentRecordService;
import com.crm.custinfo.service.IHitPackageService;
import com.crm.holidayConfig.service.IHolidayConfigService;
import com.crm.suborgConfig.domain.BaseSuborgConfig;
import com.crm.suborgConfig.service.IBaseSuborgConfigService;
import com.ruoyi.common.constant.ConfigConstant;
import com.ruoyi.common.constant.RedisConstant;
import com.ruoyi.common.constant.StatusConstant;
import com.ruoyi.common.constant.TypeConstant;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.common.core.domain.entity.SysRole;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.utils.*;
import com.ruoyi.common.utils.http.HttpPostUtil;
import com.crm.channel.domain.BaseChannel;
import com.crm.channel.service.IBaseChannelService;
import com.ruoyi.framework.datasource.DynamicDataSourceContextHolder;
import com.ruoyi.framework.websocket.WebSocketServer;
import com.ruoyi.system.service.ISysConfigService;
import com.ruoyi.system.service.ISysDeptService;
import com.ruoyi.system.service.ISysDictDataService;
import com.ruoyi.system.service.ISysUserService;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.crm.custinfo.mapper.CustInfoMapper;
import com.crm.custinfo.domain.CustInfo;
import com.crm.custinfo.service.ICustInfoService;

import static com.ruoyi.common.utils.SecurityUtils.getLoginUser;

/**
 * 客户信息Service业务层处理
 *
 * @author ruoyi
 * @date 2023-12-28
 */
@Service
public class CustInfoServiceImpl implements ICustInfoService {
    public static final Logger log = LoggerFactory.getLogger(CustInfoServiceImpl.class);
    @Autowired
    private CustInfoMapper custInfoMapper;
    @Autowired
    private ICustCommentRecordService custCommentRecordService;
    @Autowired
    private ISysDeptService iSysDeptService;
    @Autowired
    private ISysConfigService baseSysConfigService;
    @Autowired
    private RedisCache redisCache;
    @Autowired
    private ISysUserService iSysUserService;
    @Autowired
    private IBaseChannelService iBaseChannelService;
    @Autowired
    private IBaseSuborgConfigService iBaseSuborgConfigService;
    @Autowired
    private IHolidayConfigService iHolidayConfigService;
    @Autowired
    private IHitPackageService iHitPackageService;
    @Autowired
    private WebSocketServer webSocket;
    @Autowired
    private ISysDictDataService isysDictDataService;

    /**
     * 查询客户信息
     *
     * @param id 客户信息主键
     * @return 客户信息
     */
    @Override
    public CustInfo selectCustInfoById(Long id) {
        return custInfoMapper.selectCustInfoById(id);
    }

    /**
     * 查询客户信息列表
     *
     * @param custInfo 客户信息
     * @return 客户信息
     */
    @Override
    public List<CustInfo> selectCustInfoList(CustInfo custInfo) {
        return custInfoMapper.selectCustInfoList(custInfo);
    }

    /**
     * 查找单条客户信息
     *
     * @param custInfo 客户信息
     * @return 客户信息集合
     */
    @Override
    public CustInfo selectCustInfo(CustInfo custInfo) {
        return custInfoMapper.selectCustInfo(custInfo);
    }

    /**
     * 查询客户信息列表
     *
     * @param custInfo 客户信息
     * @return 客户信息
     */
    @Override
    public List<CustInfo> selectCustInfoList2(CustInfo custInfo) {
        return custInfoMapper.selectCustInfoList2(custInfo);
    }

    @Override
    public List<CustInfo> selectMyCustList(CustInfo custInfo) {
        return custInfoMapper.selectMyCustList(custInfo);
    }

    /**
     * 新增客户信息
     *
     * @param custInfo 客户信息
     * @return 结果
     */
    @Override
    public int insertCustInfo(CustInfo custInfo) {
        try {
            // 本地追加撞库包插入
            HitPackage insHitPackage = new HitPackage();
            insHitPackage.setCity(custInfo.getCity());
            insHitPackage.setMobileMd5(custInfo.getMd5val());
            insHitPackage.setMobilePrefix8Md5(Md5Encrypt.md5(custInfo.getMobile().substring(0, 8)));
            insHitPackage.setMobilePrefix7md5(Md5Encrypt.md5(custInfo.getMobile().substring(0, 7)));
            insHitPackage.setMobilePrefix9md5(Md5Encrypt.md5(custInfo.getMobile().substring(0, 9)));
            insHitPackage.setMobilePrefix10md5(Md5Encrypt.md5(custInfo.getMobile().substring(0, 10)));
            insHitPackage.setMobileSha256(Md5Encrypt.sha256(custInfo.getMobile()));
            insHitPackage.setApplyTime(custInfo.getApplyTime());
            iHitPackageService.insertHitPackage(insHitPackage);
            //异步插入到外分发器
        } catch (Exception e) {
            log.info("撞库包插入异常CustInfoServiceImpl.insertCustInfo：{}", e.getMessage());
        }
        return custInfoMapper.insertCustInfo(custInfo);
    }


    /**
     * 更新客户信息
     *
     * @param custInfo 客户信息
     * @return 结果
     */
    @Override
    public int updateCustInfo2(CustInfo custInfo) {
        return custInfoMapper.updateCustInfo(custInfo);
    }


    /**
     * 修改客户信息
     *
     * @param custInfo 客户信息
     * @return 结果
     */
    @Override
    public int updateCustInfo(CustInfo custInfo) {
        Date curDate = new Date();
        SysUser sysUser = getLoginUser().getUser();
        CustInfo info=custInfoMapper.selectCustInfoById(custInfo.getId());
        Map<String, Object> map = custInfo.getParams();
        String remarkNew = MapUtils.getString(map, "remarkNew", "");
        if (custInfo.getUserId() != null && custInfo.getUserId().longValue() == sysUser.getUserId().longValue()) { // 本人编辑保存时
            custInfo.setDeptId(sysUser.getDeptId()); // 更新为我的客户数据
            custInfo.setLastUpdateBy(sysUser.getUserId());
            custInfo.setUpdateTime(curDate);

            custInfo.setUpdateTime(DateUtils.getNowDate());

            //更新备注信息
            if (StringUtils.isNotBlank(remarkNew)) {
                custInfo.setReDistributeStatus(StatusConstant.DISTRIBUTE_STATUS_YES);// 必须有备注才移入我的客户池
                custInfo.setLastRemarkTime(curDate);

                CustCommentRecord custCommentRecord = new CustCommentRecord();
                custCommentRecord.setCustId(custInfo.getId());
                custCommentRecord.setType(4L);
                custCommentRecord.setNickName(getLoginUser().getUser().getNickName());
                custCommentRecord.setUserid(getLoginUser().getUser().getUserId());
                custCommentRecord.setRemark(remarkNew);
                custCommentRecordService.insertCustCommentRecord(custCommentRecord);
            }

        }
        if (StringUtils.isNotBlank(remarkNew)) {
            String oldRemark = StringUtils.defaultIfBlank(custInfo.getRemark(), "");
            if (StringUtils.isNotBlank(oldRemark) && StringUtils.isNotBlank(remarkNew)) {
                oldRemark = "<br>" + oldRemark;
            }

            custInfo.setRemark((StringUtils.isBlank(remarkNew) ? "" :
                    remarkNew + DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, new Date())
                            + sysUser.getNickName())  + oldRemark);
        }
        // 更新点评信息
        String dpRemarkNew = MapUtils.getString(map, "dpRemarkNew", "");

        if (StringUtils.isNotBlank(dpRemarkNew)) {
            String DpRemark = custInfo.getDpRemark();
            if (StringUtils.isNotBlank(DpRemark) && StringUtils.isNotBlank(dpRemarkNew)) {
                DpRemark = DpRemark + "<br>";
            }
            if (StringUtils.isNotBlank(dpRemarkNew)) {
                dpRemarkNew = DateUtils.getTime() + dpRemarkNew + getLoginUser().getUser().getNickName();
                custInfo.setDpRemark((StringUtils.isBlank(DpRemark) ? "" :
                        DpRemark ) + dpRemarkNew);
            }
        }
        if(custInfo.getStarLevel()!=null&&!custInfo.getStarLevel().equals(info.getStarLevel())){
            String oldStarLevelText = isysDictDataService.selectDictLabel("crm_star", info.getStarLevel());
            String newStarLevelText = isysDictDataService.selectDictLabel("crm_star", custInfo.getStarLevel());
            String remark = String.format("星级由%s变成%s", oldStarLevelText, newStarLevelText);
            CustCommentRecord custCommentRecord = new CustCommentRecord();
            custCommentRecord.setCustId(custInfo.getId());
            custCommentRecord.setType(4L);
            custCommentRecord.setNickName(getLoginUser().getUser().getNickName());
            custCommentRecord.setUserid(getLoginUser().getUser().getUserId());
            custCommentRecord.setRemark(remark);
            custCommentRecordService.insertCustCommentRecord(custCommentRecord);
        }

        return custInfoMapper.updateCustInfo(custInfo);
    }

    @Override
    public AjaxResult decryptMobile(CustInfo custInfo) {
        try {
            if (custInfo == null) return AjaxResult.error("不存在");

            String secretKey = baseSysConfigService.getItemValueByItemKey(ConfigConstant.SECRET_SERVICE_KEY, "");
            if (StringUtils.isBlank(secretKey)) {
                return AjaxResult.error("解密失败");
            }
            String[] keys = secretKey.split(",");
            String secret = Md5Encrypt.md5(keys[0] + StringUtils.defaultIfBlank(custInfo.getMd5val(), Md5Encrypt.md5(custInfo.getMobile())) + keys[1] + custInfo.getId() + keys[2]).substring(8, 24);
            return AjaxResult.success(AesUtils.decrypt(custInfo.getEncval(), new StringBuilder(secret).reverse().toString()));
        } catch (Exception e) {
            log.info("解码处理异常：{}", e.getMessage());

            return AjaxResult.error("解密失败");
        }
    }

    /**
     * 加密存储，删除明文
     *
     * @param custInfo
     * @param logger
     */
    @Override
    public void encryptMobile(CustInfo custInfo, org.slf4j.Logger logger) {
        try {
            if (custInfo == null || StringUtils.isNotBlank(custInfo.getEncval())) return;
            String secretApiUrl = baseSysConfigService.getItemValueByItemKey(ConfigConstant.SECRET_SERVICE_URL, "");
            if (StringUtils.isNotBlank(secretApiUrl)) {
                // 通过加密api服务进行机密
                Map<String, Object> params = new HashMap<>();
                params.put("id", custInfo.getId());
                params.put("mobileMd5", StringUtils.defaultIfBlank(custInfo.getMd5val(), Md5Encrypt.md5(custInfo.getMobile())));
                int i = 0;
                int code = -1;
                while (code != 0 && i < 5) {
                    // 遍历3次，失败则不再处理
                    JSONObject secResult = HttpPostUtil.postJson(secretApiUrl, params);
                    code = MapUtils.getIntValue(secResult, "code", -1);
                    if (secResult != null && code == 0) {
                        String secret = MapUtils.getString(secResult, "secret");
                        if (StringUtils.isNotBlank(secret)) {
                            custInfo.setEncval(AesUtils.encrypt(custInfo.getMobile(), new StringBuilder(secret).reverse().toString()));
                            String middle4 = custInfo.getMobile().substring(3, 7);
                            // 脱敏后的手机号码
                            custInfo.setMobile(SecurityUtil.getMobile(custInfo.getMobile()));
                            updateCustInfo(custInfo);
                            logger.info("循环第[{}]次，客户[{}][{}]处理成功", i, custInfo.getId().intValue(), middle4);
                        }
                        break;
                    } else {
                        i++;
                        logger.info("循环第[{}]次，客户[{}]处理失败[{}]", i, custInfo.getId().intValue(), secResult);
                    }
                }
            } else {
                // 本地加密
                String secretKey = baseSysConfigService.getItemValueByItemKey(ConfigConstant.SECRET_SERVICE_KEY, "");
                if (StringUtils.isBlank(secretKey)) {
                    return;
                }
                String[] keys = secretKey.split(",");
                String secret = Md5Encrypt.md5(keys[0] + StringUtils.defaultIfBlank(custInfo.getMd5val(), Md5Encrypt.md5(custInfo.getMobile())) + keys[1] + custInfo.getId() + keys[2]).substring(8, 24);
                custInfo.setEncval(AesUtils.encrypt(custInfo.getMobile(), new StringBuilder(secret).reverse().toString()));
                String middle4 = custInfo.getMobile().substring(3, 7);
                // 脱敏后的手机号码
                custInfo.setMobile(SecurityUtil.getMobile(custInfo.getMobile()));
                updateCustInfo2(custInfo);
                logger.info("客户[{}][{}]处理成功", custInfo.getId().intValue(), middle4);
            }
        } catch (Exception e) {
            logger.info("加密存储处理异常：{}", e.getMessage());
            e.printStackTrace();
        }
    }

    /**
     * 批量删除客户信息
     *
     * @param ids 需要删除的客户信息主键
     * @return 结果
     */
    @Override
    public int deleteCustInfoByIds(Long[] ids) {
        return custInfoMapper.deleteCustInfoByIds(ids);
    }

    /**
     * 删除客户信息信息
     *
     * @param id 客户信息主键
     * @return 结果
     */
    @Override
    public int deleteCustInfoById(Long id) {
        return custInfoMapper.deleteCustInfoById(id);
    }

    /**
     * 数据获取设置
     *
     * @return
     */
    @Override
    public boolean setFetchConfig(long orgId, int type, int fetchCountLimit, String fetchIsOpen) {
        try {
            if (fetchCountLimit >= 0) {
                String key = "fetchCountLimit:" + type + "_" + orgId;
                redisCache.setCacheObject(key, fetchCountLimit);
            }
            if (StringUtils.isNotBlank(fetchIsOpen)) {
                String key = "fetchIsOpen:" + type + "_" + orgId;
                redisCache.setCacheObject(key, fetchIsOpen);
            }
        } catch (Exception e) {
            log.error("数据获取设置redis操作异常", e);
            return false;
        }
        return true;
    }

    /**
     * 校验获取数据当前是否在某时间段内
     */
    @Override
    public boolean checkFetchDatalimit(String fetchTimeLimit) {
        Date curDate = new Date();
        String[] times = fetchTimeLimit.split(",");
        for (String time : times) {
            String[] times1 = time.split("-");
            if (times1.length == 2) {
                if (DateUtils.IsTimeIn(times1[0], times1[1])) {
                    return true;
                }
            }
        }
        return false;
    }

    /**
     * 个人客户/团队客户超过2,10,30天未跟进的数据
     *
     * @param type    1-个人客户 2-团队客户
     * @param roleMap
     */
    public Map<String, Object> unfollowMorethandays(String type, Map<String, Object> roleMap) {

        Map<String, Object> resMap = new HashMap<String, Object>();
        LoginUser loginUser = getLoginUser();
        SysUser user = loginUser.getUser();
        SysDept dept = iSysDeptService.selectDeptById(loginUser.getDeptId());
        String company_id = dept.getCompanyId();
        //角色
        List<SysRole> roleList = getLoginUser().getUser().getRoles();

        Long userId = loginUser.getUserId();
        Long orgId = loginUser.getDeptId();
        // 跟进中客户超过N天未跟进数量
        int unfollowCount = 0;
        int unfollowDays = 0;
        // 再分配和必跟进客户超过N天未跟进数量
        int remustCount = 0;
        int remustDays = 0;
        // 再分配超过N天未跟进数量
        int reFollowCount = 0;
        int reFollowDays = 0;
        // 必跟进客户超过N天未跟进数量
        int mustFollowCount = 0;
        int mustFollowDays = 0;
        // 待签约数据超过N天未跟进数量
        int tobesignedCount = 0;
        int tobesignedDays = 0;
        // 已上门及已签约以及已放款超过N天未跟进就抓取至公共池
        int visitsignedCount = 0;
        int visitsignedDays = 0;
        // 已上门超过N天未跟进就抓取至公共池
        int visitedCount = 0;
        int visitedDays = 0;
        // 已签约超过N天未跟进就抓取至公共池
        int signedCount = 0;
        int signedDays = 0;
        // 已放款超过N天未跟进就抓取至公共池
        int loanedCount = 0;
        int loanedDays = 0;
        Date sysdate = new Date();
        Map<String, Object> params = new HashMap<String, Object>();
        Map<String, Object> commonMap = new HashMap<String, Object>();

        if ("1".equals(type)) {
            commonMap.put("empId", userId);
        } else if ("2".equals(type)) {
            List<Long> empIds = new ArrayList<Long>();
            List<Long> orgIdsStr = new ArrayList<Long>();

            List<SysDept> sysdept = iSysDeptService.selectChildrenDeptById(orgId);

            if (MapUtils.getIntValue(roleMap, "is_store_manager", 0) == 1) {
                // 门店长查询管辖范围内的员工
                for (SysDept sysDept : sysdept) {
                    SysUser user1 = new SysUser();
                    user1.setDeptId(sysDept.getDeptId());
                    for (SysUser user2 : iSysUserService.selectUserList(user1)) {
                        empIds.add(user2.getUserId());
                    }
                    orgIdsStr.add(sysDept.getDeptId());
                }

            } else {
                SysUser user1 = new SysUser();
                user1.setDeptId(loginUser.getDeptId());
                for (SysUser user2 : iSysUserService.selectUserList(user1)) {
                    empIds.add(user2.getUserId());
                }
            }
            commonMap.put("empIds", empIds);
            commonMap.put("orgIds", orgIdsStr);
        }

        //1.跟进中客户超过2天未跟进就抓取至公共池
        unfollowDays = baseSysConfigService.getItemValueByItemKey(ConfigConstant.AUTO_FETCH_FOLLOW_DAYS, 2);

        String updateTimeEnd = DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, DateUtils.addDays(sysdate, -unfollowDays));
        params.putAll(commonMap);
        params.put("status", StatusConstant.CUST_STATUS_FOLLOW);
        params.put("updateTimeBefore", updateTimeEnd);
        //params.put("fetchFlag", "0");// 已开启自动抓取
        params.put("isDelete", TypeConstant.FLAG_NO);
        params.put("starLevelNoEqual", TypeConstant.STAR_LEVEL_6);
        params.put("channelNoEqual", TypeConstant.CHL_QRCODE);//荐介客户不可抓取
        unfollowCount = custInfoMapper.findCountByProperties(params);  //获取条数
        params.clear();

        if ("1014".equals(company_id) || "1041".equals(company_id)) {
            // 20220925 苏州富邦惠和无锡：再分配和必跟进提醒分开两个配置
            reFollowDays = baseSysConfigService.getItemValueByItemKey(ConfigConstant.AUTO_FETCH_REFOLLOW_DAYS, 2);
            updateTimeEnd = DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, DateUtils.addDays(sysdate, -reFollowDays));
            params.putAll(commonMap);
            params.put("reDistributeStatusIn", StatusConstant.DISTRIBUTE_STATUS_RE);
            params.put("updateTimeBefore", updateTimeEnd);
            params.put("isDelete", TypeConstant.FLAG_NO);
            params.put("starLevelNoEqual", TypeConstant.STAR_LEVEL_6);
            params.put("channelNoEqual", TypeConstant.CHL_QRCODE);//荐介客户不可抓取
            reFollowCount = custInfoMapper.findCountByProperties(params);
            params.clear();

            mustFollowDays = baseSysConfigService.getItemValueByItemKey(ConfigConstant.AUTO_FETCH_MUSTFOLLOW_DAYS, 2);
            updateTimeEnd = DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, DateUtils.addDays(sysdate, -mustFollowDays));

            params.putAll(commonMap);
            params.put("reDistributeStatusIn", StatusConstant.DISTRIBUTE_STATUS_MUST);
            params.put("updateTimeBefore", updateTimeEnd);
            params.put("isDelete", TypeConstant.FLAG_NO);
            params.put("starLevelNoEqual", TypeConstant.STAR_LEVEL_6);
            params.put("channelNoEqual", TypeConstant.CHL_QRCODE);//荐介客户不可抓取
            mustFollowCount = custInfoMapper.findCountByProperties(params);
            params.clear();
        } else {
            //2.再分配和必跟进客户超过2天未跟进就抓取至公共池
            remustDays = baseSysConfigService.getItemValueByItemKey(ConfigConstant.AUTO_FETCH_MUST_DAYS, 2);
            updateTimeEnd = DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, DateUtils.addDays(sysdate, -remustDays));
            params.putAll(commonMap);
            params.put("reDistributeStatusIn", StatusConstant.DISTRIBUTE_STATUS_RE + "," + StatusConstant.DISTRIBUTE_STATUS_MUST);
            params.put("updateTimeBefore", updateTimeEnd);
            //params.put("fetchFlag", "0");// 已开启自动抓取
            params.put("isDelete", TypeConstant.FLAG_NO);
            params.put("starLevelNoEqual", TypeConstant.STAR_LEVEL_6);
            params.put("channelNoEqual", TypeConstant.CHL_QRCODE);//荐介客户不可抓取
            remustCount = custInfoMapper.findCountByProperties(params);
            params.clear();
        }

        //3.待签约数据超过10天未跟进就抓取至公共池
        tobesignedDays = baseSysConfigService.getItemValueByItemKey(ConfigConstant.AUTO_FETCH_TOBESIGNED_DAYS, 10);
        updateTimeEnd = DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, DateUtils.addDays(sysdate, -tobesignedDays));
        params.putAll(commonMap);
        params.put("updateTimeBefore", updateTimeEnd);
        params.put("status", StatusConstant.CUST_STATUS_TOBESIGNED);// 待签约
        //params.put("fetchFlag", "0");// 已开启自动抓取
        params.put("isDelete", TypeConstant.FLAG_NO);
        params.put("starLevelNoEqual", TypeConstant.STAR_LEVEL_6);
        params.put("channelNoEqual", TypeConstant.CHL_QRCODE);//荐介客户不可抓取
        tobesignedCount = custInfoMapper.findCountByProperties(params);
        params.clear();
        if ("1031".equals(company_id)) {
            // 20220418新增个性化：1031-北京旭晟特殊处理，已上门及已签约以及已放款分成3个配置
            // 已上门待抓取
            visitedDays = baseSysConfigService.getItemValueByItemKey(ConfigConstant.AUTO_FETCH_VISITED_DAYS, 7);
            updateTimeEnd = DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, DateUtils.addDays(sysdate, -visitedDays));
            params.putAll(commonMap);
            params.put("updateTimeBefore", updateTimeEnd);
            params.put("status", StatusConstant.CUST_STATUS_VISIT);// 已上门
            params.put("isDelete", TypeConstant.FLAG_NO);
            params.put("starLevelNoEqual", TypeConstant.STAR_LEVEL_6);
            params.put("channelNoEqual", TypeConstant.CHL_QRCODE);//荐介客户不可抓取
            visitedCount = custInfoMapper.findCountByProperties(params);
            params.clear();
            // 已签约待抓取
            signedDays = baseSysConfigService.getItemValueByItemKey(ConfigConstant.AUTO_FETCH_SIGNED_DAYS, 15);
            updateTimeEnd = DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, DateUtils.addDays(sysdate, -signedDays));
            params.putAll(commonMap);
            params.put("updateTimeBefore", updateTimeEnd);
            params.put("status", StatusConstant.CUST_STATUS_SIGNED);
            params.put("isDelete", TypeConstant.FLAG_NO);
            params.put("starLevelNoEqual", TypeConstant.STAR_LEVEL_6);
            params.put("channelNoEqual", TypeConstant.CHL_QRCODE);//荐介客户不可抓取
            signedCount = custInfoMapper.findCountByProperties(params);
            params.clear();
            // 已放款待抓取
            loanedDays = baseSysConfigService.getItemValueByItemKey(ConfigConstant.AUTO_FETCH_LOANED_DAYS, 30);
            updateTimeEnd = DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, DateUtils.addDays(sysdate, -loanedDays));
            params.putAll(commonMap);
            params.put("updateTimeBefore", updateTimeEnd);
            params.put("status", StatusConstant.CUST_STATUS_LOAN);
            params.put("isDelete", TypeConstant.FLAG_NO);
            params.put("starLevelNoEqual", TypeConstant.STAR_LEVEL_6);
            params.put("channelNoEqual", TypeConstant.CHL_QRCODE);//荐介客户不可抓取
            loanedCount = custInfoMapper.findCountByProperties(params);
            params.clear();
        } else {
            // 已上门及已签约以及已放款超过30天未跟进就抓取至公共池
            visitsignedDays = baseSysConfigService.getItemValueByItemKey(ConfigConstant.AUTO_FETCH_VISITSIGNED_DAYS, 30);
            updateTimeEnd = DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, DateUtils.addDays(sysdate, -visitsignedDays));
            params.putAll(commonMap);
            params.put("updateTimeBefore", updateTimeEnd);
            params.put("statusin", StatusConstant.CUST_STATUS_VISIT + "," + StatusConstant.CUST_STATUS_SIGNED + "," + StatusConstant.CUST_STATUS_LOAN);// 已上门及已签约以及已放款
            //params.put("fetchFlag", "0");// 已开启自动抓取
            params.put("isDelete", TypeConstant.FLAG_NO);
            params.put("starLevelNoEqual", TypeConstant.STAR_LEVEL_6);
            params.put("channelNoEqual", TypeConstant.CHL_QRCODE);//荐介客户不可抓取
            visitsignedCount = custInfoMapper.findCountByProperties(params);
            params.clear();
        }

        resMap.put("unfollowCount", unfollowCount);
        resMap.put("unfollowDays", unfollowDays);
        resMap.put("remustCount", remustCount);
        resMap.put("remustDays", remustDays);
        resMap.put("tobesignedCount", tobesignedCount);
        resMap.put("tobesignedDays", tobesignedDays);
        resMap.put("visitsignedCount", visitsignedCount);
        resMap.put("visitsignedDays", visitsignedDays);

        resMap.put("visitedCount", visitedCount);
        resMap.put("visitedDays", visitedDays);
        resMap.put("signedCount", signedCount);
        resMap.put("signedDays", signedDays);
        resMap.put("loanedCount", loanedCount);
        resMap.put("loanedDays", loanedDays);
        resMap.put("reFollowCount", reFollowCount);
        resMap.put("reFollowDays", reFollowDays);
        resMap.put("mustFollowCount", mustFollowCount);
        resMap.put("mustFollowDays", mustFollowDays);

        return resMap;
    }

    /**
     * 获取星级数据
     *
     * @param params
     * @return
     */
    @Override
    public List<Map<String, Object>> getStarStatusDetail(Map<String, Object> params) {
        return custInfoMapper.getStarStatusDetail(params);
    }
    /**
     * 获取星级数据
     *
     * @param params
     * @return
     */
    @Override
    public List<Map<String, Object>> getStarStatusDetail2(Map<String, Object> params) {
        return custInfoMapper.getStarStatusDetail2(params);
    }
    /**
     * 将客户批量加入公共池
     *
     * @param ids 需要更新的数据主键集合
     * @return 结果
     */
    @Override
    public int batchUpdateToPublic(Long[] ids) {
        return custInfoMapper.batchUpdateToPublic(ids);
    }

    /**
     * 判断是否存在相同数据
     *
     * @param mobileMd5 加密号码
     * @return 结果
     */
    public int countByMd5(String mobileMd5) {
        return custInfoMapper.countByMd5(mobileMd5);
    }

    /**
     * 获取未指派的数据总量
     *
     * @param city 城市
     * @return 结果
     */
    @Override
    public int countByNotAssigned(String city) {
        return custInfoMapper.countByNotAssigned(city);
    }

    /**
     * 手动回收客户到待分配列表
     *
     * @param custInfo 客户信息
     * @return 客户信息集合
     */
    public int batchToBeAllocated(CustInfo custInfo) {
        return custInfoMapper.batchToBeAllocated(custInfo);
    }

    /**
     * 获取当天的用户数量
     *
     * @param params
     * @return
     */
    @Override
    public int findDistCount(Map<String, Object> params) {
        return custInfoMapper.findDistCount(params);
    }

    /**
     * 检查客户信息完整性、渠道、金额、年龄等是否满足进库基本要求
     *
     * @param custInfo
     * @param logger
     * @return
     * @throws Exception
     */
    @Override
    public Map<String, Object> checkCustInfo(CustInfo custInfo, org.slf4j.Logger logger) {
        Map<String, Object> data = new HashMap<>();
        String ERROR_NO_KEY = "errorNo";
        String ERROR_INFO_KEY = "errorInfo";
        try {
            if (custInfo == null) {
                logger.error("数据全部为空，无用申请");
                data.put(ERROR_NO_KEY, -1);
                data.put(ERROR_INFO_KEY, "数据全部为空，无用申请");
                return data;
            }
            if (StringUtils.isBlank(custInfo.getChannelSource())) {
                logger.info(String.format("......api客户数据申请:【渠道标识为空】用户%s已拒收......", custInfo.getCustName()));
                data.put(ERROR_NO_KEY, -1);
                data.put(ERROR_INFO_KEY, "渠道标识channel_source不能为空");
                return data;
            }
            if (StringUtils.isBlank(custInfo.getCity())) {
                logger.error(String.format("......api客户数据申请: 【城市为空】姓名%s已拒收......", custInfo.getCustName()));
                data.put(ERROR_NO_KEY, -1);
                data.put(ERROR_INFO_KEY, "城市不能为空");
                return data;
            }
            if (StringUtils.isBlank(custInfo.getCustName())) {
                logger.error("......api客户数据申请: 姓名为空已拒收......");
                data.put(ERROR_NO_KEY, -1);
                data.put(ERROR_INFO_KEY, "请填写姓名");
                return data;
            }
            /*if (!validateCN(custInfo.getCustName())) {
                data.put(ERROR_NO_KEY, -1);
                data.put(ERROR_INFO_KEY, "姓名必须为中文");
                return data;
            }*/
            String mobileLog = SecurityUtil.getMobile(custInfo.getMobile());
            if (StringUtils.isBlank(custInfo.getMobile()) || !custInfo.getMobile().matches("^1[3456789]\\d{9}$")) {
                logger.error(String.format("......api客户数据申请: 【手机号码格式有误】姓名%s,手机号%s......", custInfo.getCustName(), mobileLog));
                data.put(ERROR_NO_KEY, -1);
                data.put(ERROR_INFO_KEY, "手机号码格式有误");
                return data;
            }
            if (custInfo.getApplyLimit() == null) {
                logger.error(String.format("......api客户数据申请: 【申请金额有误或受限制】姓名%s,手机号%s，金额%s......", custInfo.getCustName(), mobileLog, custInfo.getApplyLimit()));
                data.put(ERROR_NO_KEY, -1);
                data.put(ERROR_INFO_KEY, "申请金额有误或受限制");
                return data;
            }
            // 查询城市所有的分公司
            String cityName = custInfo.getCity();
            /*if (cityName.length() >= 2) {
                cityName = cityName.substring(0, 2);
                custInfo.setCity(cityName);
            }*/
            custInfo.setCity(cityName.replace("市", ""));
            Long[] orgIds = getOrgIdsByCity(custInfo.getCity());
            if (orgIds.length == 0) {
                logger.error(String.format("......api客户数据申请:【城市不存在】城市%s,渠道%s,用户%s,手机号%s已拒收......", cityName, custInfo.getChannelSource(), custInfo.getCustName(), mobileLog));
                data.put(ERROR_NO_KEY, -1);
                data.put(ERROR_INFO_KEY, "api不支持该城市");
                return data;
            }
            BaseChannel channel = iBaseChannelService.getChannelInfo(custInfo.getChannelSource(), custInfo.getCity());
            // 校验渠道城市是否存在
            if (channel == null) {
                logger.error(String.format("......api客户数据申请: 【城市%s渠道%s不存在】姓名%s,手机号%s已拒收......", custInfo.getCity(), custInfo.getChannelSource(), custInfo.getCustName(), mobileLog));
                data.put(ERROR_NO_KEY, -1);
                data.put(ERROR_INFO_KEY, "渠道不存在");
                return data;
            }
            //  20210711: 增加城市渠道是否接收数据判断  --
            if (channel.getOpenFlag() == 2) {
                data.put(ERROR_NO_KEY, -1);
                data.put(ERROR_INFO_KEY, "该城市已暂停数据接收");
                return data;
            }
            // 校验渠道金额限制
            if (custInfo.getApplyLimit().compareTo(new BigDecimal(channel.getApplyLimit())) < 0) {
                logger.error(String.format("......api客户数据申请: 【渠道%s申请金额有误或受限制】姓名%s,手机号%s，金额%s......", custInfo.getChannelSource(), custInfo.getCustName(), mobileLog, custInfo.getApplyLimit()));
                data.put(ERROR_NO_KEY, -1);
                data.put(ERROR_INFO_KEY, "申请金额有误或受限制");
                return data;
            }
            // 校验渠道年龄限制
            if (custInfo.getAge().intValue() < channel.getAgeLimit()) {
                logger.error(String.format("......api客户数据申请: 【渠道%s年龄受限制】姓名%s,手机号%s,金额%s......", custInfo.getChannelSource(), custInfo.getCustName(), mobileLog, custInfo.getApplyLimit()));
                data.put(ERROR_NO_KEY, -1);
                data.put(ERROR_INFO_KEY, "年龄有误或受限制");
                return data;
            }
            data.put(ERROR_NO_KEY, 0);
        } catch (Exception e) {
            logger.error("客户信息检查异常", e);
            data.put(ERROR_NO_KEY, -1);
            data.put(ERROR_INFO_KEY, "客户信息检查异常");
        }
        return data;
    }

    /**
     * 获取对应城市的部门ids
     *
     * @param cityName
     * @return
     */
    @Override
    public Long[] getOrgIdsByCity(String cityName) {
        if (StringUtils.isNotBlank(cityName)) {
            cityName = cityName.replace("市", "");
        }
        List<BaseSuborgConfig> citys = iBaseSuborgConfigService.getByCity(cityName);
        List<SysDept> sysDepts = new ArrayList<SysDept>();
        for (BaseSuborgConfig city : citys) {
            sysDepts.addAll(iSysDeptService.selectChildrenAllDeptById(city.getOrgId()));
        }
        List<Long> depts = new ArrayList<Long>();
        for (SysDept sysDept : sysDepts) {
            depts.add(sysDept.getDeptId());
        }
        return depts.toArray(new Long[0]);

    }

    /**
     * 新数据分配给原客户经理
     *
     * @param custInfo
     * @param lastCustId
     * @param lastUser
     * @param logger
     * @return
     */
    @Override
    public boolean dealCustReplay(CustInfo custInfo, Long lastCustId, SysUser lastUser, org.slf4j.Logger logger) {
        try {
            String mobileLog = SecurityUtil.getMobile(custInfo.getMobile());
            custInfo.setEmpId(lastUser.getUserId());
            custInfo.setOrgId(lastUser.getDeptId());
            //custInfo.setDistributeTime(new Date());
            custInfo.setOldDistributeTime(new Date()); // 第一次分配时间
            custInfo.setDistributeRemark(String.format("%s:数据中心初始分配给%s",
                    DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, new Date()), lastUser.getNickName()));
            custInfo.setStatus(StatusConstant.CUST_STATUS_UNACCEPT);// 未处理
            custInfo.setReDistributeStatus(StatusConstant.DISTRIBUTE_STATUS_YES); // 已分配
            custInfo.setStarLevel("0");
            custInfo.setOldEmpId(lastUser.getUserId());
            custInfo.setOldUserId(lastUser.getUserId());
            if (custInfo.getApplyTime() == null) {
                custInfo.setApplyTime(new Date());
            }
            insertCustInfo(custInfo);
            encryptMobile(custInfo, logger);
            logger.info(String.format("......api客户数据接收:【重复申请】用户%s,手机号%s已归类到原客户经理%s名下......", custInfo.getCustName(), mobileLog, lastUser.getNickName()));
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("新数据分配给原客户经理异常", e);
            return false;
        } finally {
            dealDuplicateData(lastCustId, custInfo, true);
        }
        return true;
    }

    /**
     * 处理重复数据逻辑
     * <li>重复数据进系统以后，自动将之前的同手机号的数据加入垃圾池，并同步最近一条有客户经理归属的数据的备注，
     * 如果所有数据均无客户经理归属则取最近一条数据的备注。</li>
     *
     * @param lastCustId
     * @param custInfo
     * @param needDeleteLast 是否需要移除最后一条重复数据
     */
    public void dealDuplicateData(Long lastCustId, CustInfo custInfo, boolean needDeleteLast) {
        if (lastCustId != null && lastCustId > 0 && custInfo != null && custInfo.getId() != null && custInfo.getId() > 0) {
            // 同步最近一条客户数据的备注到这条新数据里面
            CustCommentRecord lastCommentRecord = new CustCommentRecord();
            lastCommentRecord.setCustId(lastCustId);

            List<CustCommentRecord> comments = custCommentRecordService.selectCustCommentRecordList(lastCommentRecord);
            List<CustCommentRecord> newComments = new ArrayList<CustCommentRecord>();
            for (int i = comments.size() - 1; i >= 0; i--) {
                CustCommentRecord comment = comments.get(i);
                comment.setCustId(custInfo.getId());
                // 保存之前的客户备注
                custCommentRecordService.insertCustCommentRecord(comment);
            }
            // 生成一条新的备注
            CustCommentRecord record = new CustCommentRecord();
            record.setCustId(custInfo.getId());
            record.setEmpId(null);
            record.setEmpName("系统自动备注");
            record.setRemark("客户再次申请");
            record.setType(4L);
            record.setType2(4L);
            record.setCreateTime(new Date());

            custCommentRecordService.insertCustCommentRecord(record);
            // 上一条为重复数据归入垃圾库。
            if (needDeleteLast) {
                log.info("自动找妈妈分配后，删除原客户id={}", lastCustId);
                CustInfo info = selectCustInfoById(lastCustId);
                if (info != null) {
                    info.setIsDelete(TypeConstant.FLAG_YES);
                    info.setDistributeRemark(info.getDistributeRemark() + "<br>" +
                            DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, new Date()) + " 用户再次申请，该数据自动移除到垃圾库");
                    info.setUpdateTime(new Date());
                    this.updateCustInfo(info);
                }
            }
        }

    }

    /**
     * 新数据随机分配
     *
     * @param custInfo  待分配的客户信息
     * @param orgIds    可分配的部门ids
     * @param checkTime 是否检查分配时间
     * @param logger
     * @return
     */
    @Override
    public boolean dealCustRandomly(CustInfo custInfo, Long[] orgIds, boolean checkTime, boolean isSwitch, org.slf4j.Logger logger) {
        try {
            if (custInfo.getApplyTime() == null) {
                custInfo.setApplyTime(new Date());
            }
            String mobileLog = SecurityUtil.getMobile(custInfo.getMobile());
            if (checkTime) {
                String distriAllowTime = getDistriAllowTime();
                if (!checkFetchDatalimit(distriAllowTime)) {
                    if (StringUtils.isBlank(custInfo.getStatus())) {
                        custInfo.setStatus(StatusConstant.CUST_STATUS_UNALLOCATED);//未指派

                        this.saveOrUpdate(custInfo);
                    }
                    logger.info(String.format("......api客户数据入库:【未指派】用户%s,手机号%s未被分配，当前非分配时间......", custInfo.getCustName(), mobileLog));
                    return true;
                }
            }
            List<SysUser> userList = getRecNewDataUsersByCity(custInfo.getCity(), orgIds, isSwitch, custInfo.getChannelSource());
            if (!userList.isEmpty()) {
                SysUser user = userList.get(0);
                custInfo.setUserId(user.getUserId());
                custInfo.setDeptId(user.getDeptId());
                custInfo.setOldDistributeTime(new Date());
                custInfo.setDistributeRemark(String.format("%s:数据中心初始分配给%s", DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, new Date()), user.getNickName()));
                custInfo.setStatus(StatusConstant.CUST_STATUS_UNACCEPT);//未处理
                custInfo.setReDistributeStatus(StatusConstant.DISTRIBUTE_STATUS_YES);// 已分配
                custInfo.setStarLevel("0");
                custInfo.setOldEmpId(user.getUserId());
                custInfo.setOldUserId(user.getUserId());
                this.saveOrUpdate(custInfo);
                encryptMobile(custInfo, logger);
//                try {
//                    webSocket.onSendByUserId(JSONObject.from(param).toString(),user.getUserName());
//                } catch (Exception e) {
//                    logger.error("通知异常", e);
//                }

                Map<String, Object> param = new HashMap<>();

                String tenantId = DynamicDataSourceContextHolder.getDataSourceKey();
                param.put("noticeContent", "客户【" + custInfo.getCustName() + "】待跟进，请尽快处理！");
                param.put("noticeType", "1");//客户待跟进提醒
                param.put("custId", custInfo.getId());
                param.put("custName", custInfo.getCustName());
                logger.info("......api客户数据入库:【已分配】用户{}手机号{}已分配至{}名下,租户{}......", custInfo.getCustName(), mobileLog, user.getNickName(),tenantId);
                webSocket.onSendByUserId(JSONObject.from(param).toString(), tenantId+"_!_"+user.getUserName());

                logger.info(String.format("......api客户数据入库:【已分配】用户%s,手机号%s已分配至%s名下......", custInfo.getCustName(), mobileLog, user.getNickName()));
            } else { // 无可分配的用户
                if (StringUtils.isBlank(custInfo.getStatus())) {
                    custInfo.setStatus(StatusConstant.CUST_STATUS_UNALLOCATED);//未指派
                }
                logger.info(String.format("......api客户数据入库:【未指派】用户%s,手机号%s未被分配，当前客户经理数据池已满......", custInfo.getCustName(), mobileLog));
                this.saveOrUpdate(custInfo);
            }
            //pool.submit(new SendSmsThread(custInfo));
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("新数据随机分配异常", e);
            return false;
        }
        return true;
    }

    /**
     * 客户数据统计报表专用
     *
     * @param params
     * @return
     */
    @Override
    public List<Map<String, Object>> commonStatics(Map<String, Object> params) {
        int reportType = MapUtils.getIntValue(params, "reportType", 0); // 报表类别
        String statementName = MapUtils.getString(TypeConstant.reportType, reportType, "");
        if (StringUtils.isNotBlank(statementName)) {
            //看一下是否要做成动态配置
//            return getSqlMapClientTemplate().queryForList(statementName,params);
        }
        return new ArrayList<Map<String, Object>>();
    }

    public void saveOrUpdate(CustInfo entity) {
        if (entity.getId() == null || entity.getId() == 0) insertCustInfo(entity);
        else updateCustInfo2(entity);
    }

    /**
     * 新数据允许分配的时间
     *
     * @return
     */
    public String getDistriAllowTime() {
        String distriAllowTime = baseSysConfigService.getItemValueByItemKey(ConfigConstant.CUST_DATA_DISTRI_ALOW_TIME, "09:00-21:00");
        Date date = new Date();
//        int company_id = ConfigProperties.get("company.id", 0);
//        if (company_id == 1031) {
//            // 20220901北京旭晟个性处理 周六周天固定10:08开始分配
//            if (DateUtils.isFriday(date)) {
//                distriAllowTime = baseSysConfigService.getItemValueByItemKey(ConfigConstant.CUST_DATA_DISTRI_ALOW_TIME_V2, "09:00-18:00");
//            } else if (DateUtils.isSaturday(date) || DateUtils.isSunday(date)) {
//                distriAllowTime = baseSysConfigService.getItemValueByItemKey("cust.data.distri.allow.time.67", "10:08-18:00");
//            }
//        } else if (company_id == 1059) {
//            // 20230506泰州轩茂个性处理 周1-5分发时间8点半开始，周末和节假日则是9点开始
//            if (holidayConfigService.isHoliday(date) || DateUtils.isSaturday(date) || DateUtils.isSunday(date)) {
//                distriAllowTime = baseSysConfigService.getItemValueByItemKey(ConfigConstant.CUST_DATA_DISTRI_ALOW_TIME_V2, "");
//            }
//        } else {
//            if (DateUtils.isFriday(date) || DateUtils.isSunday(date)) {
//                distriAllowTime = baseSysConfigService.getItemValueByItemKey(ConfigConstant.CUST_DATA_DISTRI_ALOW_TIME_V3, "");
//                if (StringUtils.isNotBlank(distriAllowTime)) {
//                    // 北京禾众升周五周天分配时间调整到下午18:30
//                    return distriAllowTime;
//                } else {
//                    distriAllowTime = baseSysConfigService.getItemValueByItemKey(ConfigConstant.CUST_DATA_DISTRI_ALOW_TIME_V2, "09:00-18:00");
//                }
//            } else if (DateUtils.isSaturday(date) || holidayConfigService.isHoliday(date)) {
//                // 周五周六周天(以及节假日)分配时间不一样
//                distriAllowTime = baseSysConfigService.getItemValueByItemKey(ConfigConstant.CUST_DATA_DISTRI_ALOW_TIME_V2, "09:00-18:00");
//            }
//        }
        //所有的分公司按照同一个规则分配时间
        if (DateUtils.isFriday(date) || DateUtils.isSunday(date)) {
            distriAllowTime = baseSysConfigService.getItemValueByItemKey(ConfigConstant.CUST_DATA_DISTRI_ALOW_TIME_V3, "");
            if (StringUtils.isNotBlank(distriAllowTime)) {
                // 北京禾众升周五周天分配时间调整到下午18:30
                return distriAllowTime;
            } else {
                distriAllowTime = baseSysConfigService.getItemValueByItemKey(ConfigConstant.CUST_DATA_DISTRI_ALOW_TIME_V2, "09:00-18:00");
            }
        } else if (DateUtils.isSaturday(date) || iHolidayConfigService.isHoliday(date)) {
            // 周五周六周天(以及节假日)分配时间不一样
            distriAllowTime = baseSysConfigService.getItemValueByItemKey(ConfigConstant.CUST_DATA_DISTRI_ALOW_TIME_V2, "09:00-18:00");
        }
        return distriAllowTime;
    }

    /**
     * 根据城市配置开关和指定分配部门查询当前城市下可接收数据分配的用户
     *
     * @param city
     * @param orgIds
     * @param isSwith       是否切换分公司入库
     * @param channelSource 媒体信息
     * @return
     */
    public List<SysUser> getRecNewDataUsersByCity(String city, Long[] orgIds, boolean isSwith, String channelSource) {
        List<Long> receiveOrgIds = new ArrayList<>();//正常接收数据的分公司下的部门
        List<Long> noreceiveOrgIds = new ArrayList<>();//已暂停数据接收的分公司下的部门
        List<SysDept> receiveOrgList = new ArrayList<SysDept>();//正常接收数据的分公司下的部门
        List<SysDept> noreceiveOrgList = new ArrayList<SysDept>();//已暂停数据接收的分公司下的部门
        List<BaseSuborgConfig> suborgList = iBaseSuborgConfigService.getByCity(city);
        for (BaseSuborgConfig suborgConfig : suborgList) {
            if (TypeConstant.FLAG_YES.equals(suborgConfig.getDistributeStatus())) {
                receiveOrgList.addAll(iSysDeptService.selectChildrenAllDeptById(suborgConfig.getOrgId()));
            } else {
                noreceiveOrgList.addAll(iSysDeptService.selectChildrenAllDeptById(suborgConfig.getOrgId()));
            }
        }
        List<SysUser> userList = new ArrayList<>();
        if (!receiveOrgList.isEmpty()) {
            for (SysDept sysDept : receiveOrgList) {
                receiveOrgIds.add(sysDept.getDeptId());
            }
            SysUser userInparam = new SysUser();
            Map<String, Object> params = new HashMap<String, Object>();
            if (suborgList.size() >= 2) { // 同一个城市存在两个以上分公司时的处理方式：可能存在一个打开一个关闭的情况
                // 目前切换分公司入库的规则只有上海，上海只有1个分公司， 该条件暂不适用于上海
                params.put("deptIds", receiveOrgIds.toArray(new Long[0]));
            } else {
                params.put("deptIds", orgIds);
            }
            userInparam.setParams(params);
            userList.addAll(iSysUserService.findAllCanRecNewUsers(userInparam));

        }
        if (!noreceiveOrgList.isEmpty()) {
            SysUser userInparam = new SysUser();
            Map<String, Object> params = new HashMap<String, Object>();
            if (isSwith) {
                // 切换分公司入库只能查切换分组下的打开了自助数据接收的用户
                params.put("deptIds", orgIds);
            } else {
                for (SysDept sysDept : noreceiveOrgList) {
                    noreceiveOrgIds.add(sysDept.getDeptId());
                }
                params.put("deptIds", noreceiveOrgIds);
            }
            params.put("isSelfRec", "1");
            userInparam.setParams(params);
            userList.addAll(iSysUserService.findAllCanRecNewUsers(userInparam));
        }

        return userList;
    }

    /**
     * 自动任务分配
     */
    @Override
    public void autoDistributeCustDatas() {
        log.info("......自动任务分配开始......");
        // 允许分配的时间
        String distriAllowTime = getDistriAllowTime();
        if (!checkFetchDatalimit(distriAllowTime)) {
            log.info(String.format("......自动任务分配结束: 仅在%s进行分配......", distriAllowTime));
            return;
        }
        String auto_distribute_flag = redisCache.getCacheObject(RedisConstant.AUTO_DISTRIBUTE_FLAG);
        log.info("......自动任务分配标识：auto_distribute_flag = " + auto_distribute_flag);
        if (StringUtils.isBlank(auto_distribute_flag) || TypeConstant.FLAG_YES.equals(auto_distribute_flag)) {
            // 如果任务未执行或者已执行完毕，则可允许执行
            int distri_time_interval = baseSysConfigService.getItemValueByItemKey(ConfigConstant.CUST_DATA_DISTRI_TIME_INTERVAL, 120);

            redisCache.setCacheObject(RedisConstant.AUTO_DISTRIBUTE_FLAG, TypeConstant.FLAG_NO, 60 * distri_time_interval, TimeUnit.SECONDS);// 120分钟自动过期
        } else {
            log.info("......自动任务分配尚未完成: 本次分配任务终止......");
            return;
        }
        // 查询所有待分配客户列表
        CustInfo inParams = new CustInfo();
        inParams.setStatus(StatusConstant.CUST_STATUS_UNALLOCATED);
        List<CustInfo> custlist = selectCustInfoList(inParams);

        int num = 0;
        for (CustInfo custInfo : custlist) {
            try {
                boolean result = autoDistributeDataV1(custInfo, false);
                if (result && !custInfo.getStatus().equals(StatusConstant.CUST_STATUS_UNALLOCATED)) {
                    num++;
                }
            } catch (Exception e) {
                log.error("自动任务分配异常", e);
            }
        }
        redisCache.setCacheObject(RedisConstant.AUTO_DISTRIBUTE_FLAG, TypeConstant.FLAG_YES);// 120分钟自动过期
        log.info(String.format("......自动任务分配完毕， 本次成功分配数据数[%s]", num));
    }

    /**
     * 自动数据入库分配-非上海
     *
     * @param custInfo
     * @param checkTime
     * @return
     */
    public boolean autoDistributeDataV1(CustInfo custInfo, boolean checkTime) {
        try {
            // 随机分配

            // 随机分配
            Long[] orgIds = getOrgIdsByCity(custInfo.getCity());
            return dealCustRandomly(custInfo, orgIds, true, false, log);
        } catch (Exception e) {
            e.printStackTrace();
            log.error("数据自动分配V1异常", e);
        }
        return false;
    }
    /**
     * 获取手机号前8位
     * @param mobile
     * @return
     */
    @Override
    public List<String> getLikeMobile(String mobile){
        List<String> result = new ArrayList<String>();
        String mobile2 = mobile.substring(0,3);
        Map<String, Object> params= new HashMap<String, Object>();
        params.put("mobile", mobile2);
        //查询出前三位的号码
        List<Map<String, Object>> list=this.getCustInfoByMobilePrevious3(params);
        for (Map<String, Object> map : list) {
            CustInfo custInfo=new CustInfo();
            custInfo.setId(MapUtils.getLong(map,"id"));
            custInfo.setMobile(MapUtils.getString(map,"mobile"));
            custInfo.setMd5val(MapUtils.getString(map,"md5val"));
            custInfo.setEncval(MapUtils.getString(map,"encval"));
            //解密
            AjaxResult resultPhone = decryptMobile(custInfo);
            String phone = resultPhone.get("msg").toString();
            if(phone.length()==11&&phone.substring(0,8).equals(mobile)){
                result.add(MapUtils.getString(map,"md5val"));
            }
        }
        return result;
    }
    /**
     * 根据号码的前三位匹配数据
     *
     * @param params 获取数据的集合
     * @return 结果
     */
    @Override
    public List<Map<String, Object>> getCustInfoByMobilePrevious3(Map<String, Object> params){
        return custInfoMapper.getCustInfoByMobilePrevious3(params);
    }
}
